package com.example.monitordemo.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSON;
import lombok.experimental.UtilityClass;

import java.util.Date;

import static com.example.monitordemo.config.MonitorConfig.JVM_APPLICATION;
import static com.example.monitordemo.config.MonitorConfig.JVM_INSTANCE;
import static com.example.monitordemo.constant.CommonConstant.API_PREFIX;
import static com.example.monitordemo.constant.CommonConstant.INSTANT_QUERY_PREFIX;
import static com.example.monitordemo.constant.JVMConstant.*;

@UtilityClass
public class JvmMonitorUtil {

    /**`
     * promQL语句
     */
    String promQl;

    /**
     * SLA百分比
     * @return
     */
    public JSON slaPercent(Date time,String instance,String application){
        return getJson(time, instance, application, SLA_PERCENT);
    }



    /**
     * 进程启动时长
     * @return
     */
    public JSON processUpTime(Date time,String instance,String application){
        return getJson(time, instance, application, PROCESS_UP_TIME);
    }
    /**
     * 堆内存使用率
     * @return
     */
    public JSON memoryUseRate(Date time,String instance,String application){
        return getJson(time, instance, application, MEMORY_USE_RATE);
    }
    /**
     * 非堆内存使用率
     * @return
     */
    public JSON notMemoryUseRate(Date time,String instance,String application){
        return getJson(time,instance,application,NOT_MEMORY_USE_RATE);
    }
    /**
     * QPS(1分钟平均)
     * @return
     */
    public JSON qpsMinute(Date time,String instance,String application){
        return getJson(time,instance,application,QPS_MINUTE);
    }
    /**
     * 错误数(1分钟平均)
     * @return
     */
    public JSON errorNumMinute(Date time,String instance,String application){
        return getJson(time,instance,application,ERROR_NUM_MINUTE);
    }
    /**
     * 请求耗时(1分钟平均) 最大
     * @return
     */
    public JSON requestTimeMax(Date time,String instance,String application){
     return getJson(time,instance,application,REQUEST_TIME_MAX);
    }
    /**
     * 请求耗时(1分钟平均) 平均
     * @return
     */
    public JSON requestTimeAvg(Date time,String instance,String application){
        return getJson(time,instance,application,REQUEST_TIME_AVG);
    }
    /**
     * 饱和度-tomcat忙线程
     * @return
     */
    public JSON tomcatBusyThreads(Date time,String instance,String application){
        return getJson(time,instance,application,TOMCAT_BUSY_THREADS);
    }
    /**
     * 饱和度-tomcat当前线程
     * @return
     */
    public JSON tomcatCurrentThreads(Date time,String instance,String application){
        return getJson(time,instance,application,TOMCAT_CURRENT_THREADS);
    }
    /**
     * 饱和度-tomcat配置最大线程
     * @return
     */
    public JSON tomcatConfigMaxThreads(Date time,String instance,String application){
        return getJson(time,instance,application,TOMCAT_CONFIG_MAX_THREADS);
    }
    /**
     * 饱和度-jetty忙线程
     * @return
     */
    public JSON jettyBusyThreads(Date time,String instance,String application){
        return getJson(time,instance,application,JETTY_BUSY_THREADS);
    }
    /**
     * 饱和度-jetty当前线程
     * @return
     */
    public JSON jettyCurrentThreads(Date time,String instance,String application){
        return getJson(time,instance,application,JETTY_CURRENT_THREADS);
    }
    /**
     * 饱和度-jetty配置最大线程
     * @return
     */
    public JSON jettyConfigMaxThreads(Date time,String instance,String application){
        return getJson(time,instance,application,JETTY_CONFIG_MAX_THREADS);
    }
    /**
     * 平均响应时间
     * @return
     */
    public JSON avgResponseTime(Date time,String instance,String application){
        return getJson(time,instance,application,AVG_RESPONSE_TIME);
    }
    /**
     * P95响应时间
     * @return
     */
    public JSON p95ResponseTime(Date time,String instance,String application){
        return getJson(time,instance,application,P95_RESPONSE_TIME);
    }
    /**
     * Top10请求
     * @return
     */
    public JSON top10Request(Date time,String instance,String application){
        return getJson(time,instance,application, COUNT_TOP10_REQUEST);
    }
    /**
     * 系统CPU使用率
     * @return
     */
    public JSON systemCpuUseRate(Date time,String instance,String application){
        return getJson(time,instance,application,SYSTEM_CPU_USE_RATE);
    }
    /**
     * 进程CPU使用率
     * @return
     */
    public JSON processCpuUseRate(Date time,String instance,String application){
        return getJson(time,instance,application,PROCESS_CPU_USE_RATE);
    }
    /**
     * 平均进程CPU使用率
     * @return
     */
    public JSON avgProcessCpuUseRate(Date time,String instance,String application){
        return getJson(time,instance,application,AVG_PROCESS_CPU_USE_RATE);
    }
    /**
     * 负载
     * @return
     */
    public JSON load(Date time,String instance,String application){
        return getJson(time,instance,application,LOAD);
    }
    /**
     * 活线程数
     * @return
     */
    public JSON liveThreads(Date time,String instance,String application){
        return getJson(time,instance,application,LIVE_THREADS);
    }
    /**
     * 守护线程数
     * @return
     */
    public JSON daemonThreads(Date time,String instance,String application){
        return getJson(time,instance,application,DAEMON_THREADS);
    }
    /**
     * 自Java虚拟机启动或峰值重置以来的最高活动线程数。
     * @return
     */
    public JSON peakThreads(Date time,String instance,String application){
        return getJson(time,instance,application,PEAK_THREADS);
    }
    /**
     * 各状态线程数
     * @return
     */
    public JSON statesThreads(Date time,String instance,String application){
        return getJson(time,instance,application,STATES_THREADS);
    }
    /**
     * Logback日志数
     * @return
     */
    public JSON logbackNum(Date time,String instance,String application){
        return getJson(time,instance,application,LOGBACK_NUM);
    }
    /**
     * 文件描述符-进程打开文件数
     * @return
     */
    public JSON processOpenFiles(Date time,String instance,String application){
        return getJson(time,instance,application,PROCESS_OPEN_FILES);
    }
    /**
     * 文件描述符-进程最大文件数
     * @return
     */
    public JSON processMaxFiles(Date time,String instance,String application){
        return getJson(time,instance,application,PROCESS_MAX_FILES);
    }
    /**
     * 堆内存-已用内存
     * @return
     */
    public JSON heapUsedMemory(Date time,String instance,String application){
        return getJson(time,instance,application,HEAP_USED_MEMORY);
    }
    /**
     * 堆内存-可用内存
     * @return
     */
    public JSON heapUsableMemory(Date time,String instance,String application){
        return getJson(time,instance,application,HEAP_USABLE_MEMORY);
    }
    /**
     * 堆内存-最大内存
     * @return
     */
    public JSON heapMaxMemory(Date time,String instance,String application){
        return getJson(time,instance,application,HEAP_MAX_MEMORY);
    }
    /**
     * 非堆内存-已用内存
     * @return
     */
    public JSON notHeapUsedMemory(Date time,String instance,String application){
        return getJson(time,instance,application,NOT_HEAP_USED_MEMORY);
    }
    /**
     * 非堆内存-可用内存
     * @return
     */
    public JSON notHeapUsableMemory(Date time,String instance,String application){
        return getJson(time,instance,application,NOT_HEAP_USABLE_MEMORY);
    }
    /**
     * 非堆内存-最大内存
     * @return
     */
    public JSON notHeapMaxMemory(Date time,String instance,String application){
        return getJson(time,instance,application,NOT_HEAP_MAX_MEMORY);
    }
    /**
     * 总内存-已用内存
     * @return
     */
    public JSON usedMemory(Date time,String instance,String application){
        return getJson(time,instance,application,USED_MEMORY);
    }
    /**
     * 总内存-可用内存
     * @return
     */
    public JSON usableMemory(Date time,String instance,String application){
        return getJson(time,instance,application,USABLE_MEMORY);
    }
    /**
     * 总内存-最大内存
     * @return
     */
    public JSON maxMemory(Date time,String instance,String application){
        return getJson(time,instance,application,MAX_MEMORY);
    }
    /**
     * JVM进程内存-vss
     * @return
     */
    public JSON processMemoryVssBytes(Date time,String instance,String application){
        return getJson(time,instance,application,PROCESS_MEMORY_VSS_BYTES);
    }
    /**
     * JVM进程内存-rss
     * @return
     */
    public JSON processMemoryRssBytes(Date time,String instance,String application){
        return getJson(time,instance,application,PROCESS_MEMORY_RSS_BYTES);
    }
    /**
     * JVM进程内存-swap
     * @return
     */
    public JSON processMemorySwapBytes(Date time,String instance,String application){
        return getJson(time,instance,application,PROCESS_MEMORY_SWAP_BYTES);
    }
    /**
     * JVM进程内存-rss+swap
     * @return
     */
    public JSON processMemoryRssSwapBytes(Date time,String instance,String application){
        return getJson(time,instance,application,PROCESS_MEMORY_RSS_SWAP_BYTES);
    }
    /**
     * JVM堆内存详细-PS Eden Space 已用
     * @return
     */
    public JSON psEdenSpaceUsed(Date time,String instance,String application){
        return getJson(time,instance,application,PS_EDEN_SPACE_USED);
    }
    /**
     * JVM堆内存详细-PS Eden Space 可用
     * @return
     */
    public JSON psEdenSpaceUsable(Date time,String instance,String application){
        return getJson(time,instance,application,PS_EDEN_SPACE_USABLE);
    }
    /**
     * JVM堆内存详细-PS Eden Space 总共
     * @return
     */
    public JSON psEdenSpaceMax(Date time,String instance,String application){
        return getJson(time,instance,application,PS_EDEN_SPACE_MAX);
    }
    /**
     * JVM堆内存详细-PS Old Gen 已用
     * @return
     */
    public JSON psOldGenUsed(Date time,String instance,String application){
        return getJson(time,instance,application,PS_OLD_GEN_USED);
    }
    /**
     * JVM堆内存详细-PS Old Gen 可用
     * @return
     */
    public JSON psOldGenUsable(Date time,String instance,String application){
        return getJson(time,instance,application,PS_OLD_GEN_USABLE);
    }
    /**
     * JVM堆内存详细-PS Old Gen 总共
     * @return
     */
    public JSON psOldGenMax(Date time,String instance,String application){
        return getJson(time,instance,application,PS_OLD_GEN_MAX);
    }
    /**
     * JVM堆内存详细-PS Survivor Space 已用
     * @return
     */
    public JSON psSurvivorSpaceUsed(Date time,String instance,String application){
        return getJson(time,instance,application,PS_SURVIVOR_SPACE_USED);
    }
    /**
     * JVM堆内存详细-PS Survivor Space 可用
     * @return
     */
    public JSON psSurvivorSpaceUsable(Date time,String instance,String application){
        return getJson(time,instance,application,PS_SURVIVOR_SPACE_USABLE);
    }
    /**
     * JVM堆内存详细-PS Survivor Space 总共
     * @return
     */
    public JSON psSurvivorSpaceMax(Date time,String instance,String application){
        return getJson(time,instance,application,PS_SURVIVOR_SPACE_MAX);
    }
    /**
     * JVM非堆内存详细-Metaspace已用
     * @return
     */
    public JSON metaspaceUsed(Date time,String instance,String application){
        return getJson(time,instance,application,METASPACE_USED);
    }
    /**
     * JVM非堆内存详细-Metaspace可用
     * @return
     */
    public JSON metaspaceUsable(Date time,String instance,String application){
        return getJson(time,instance,application,METASPACE_USABLE);
    }
    /**
     * JVM非堆内存详细-Metaspace总共
     * @return
     */
    public JSON metaspaceMax(Date time,String instance,String application){
        return getJson(time,instance,application,METASPACE_MAX);
    }
    /**
     * JVM非堆内存详细-Compressed Class Space已用
     * @return
     */
    public JSON compressedClassSpaceUsed(Date time,String instance,String application){
        return getJson(time,instance,application,COMPRESSED_CLASS_SPACE_USED);
    }
    /**
     * JVM非堆内存详细-Compressed Class Space可用
     * @return
     */
    public JSON compressedClassSpaceUsable(Date time,String instance,String application){
        return getJson(time,instance,application,COMPRESSED_CLASS_SPACE_USABLE);
    }
    /**
     * JVM非堆内存详细-Compressed Class Space总共
     * @return
     */
    public JSON compressedClassSpaceMax(Date time,String instance,String application){
        return getJson(time,instance,application,COMPRESSED_CLASS_SPACE_MAX);
    }
    /**
     * JVM非堆内存详细-Code Cache已用
     * @return
     */
    public JSON codeCacheUsed(Date time,String instance,String application){
        return getJson(time,instance,application,CODE_CACHE_USED);
    }
    /**
     * JVM非堆内存详细-Code Cache可用
     * @return
     */
    public JSON codeCacheUsable(Date time,String instance,String application){
        return getJson(time,instance,application,CODE_CACHE_USABLE);
    }
    /**
     * JVM非堆内存详细-Code Cache总共
     * @return
     */
    public JSON codeCacheMax(Date time,String instance,String application){
        return getJson(time,instance,application,CODE_CACHE_MAX);
    }
    /**
     * 垃圾回收（GC）- GC 次数
     * @return
     */
    public JSON gcTimes(Date time,String instance,String application){
        return getJson(time,instance,application,GC_TIMES);
    }
    /**
     * 垃圾回收（GC）- 平均GC暂停时间
     * @return
     */
    public JSON avgGcPauseTime(Date time,String instance,String application){
        return getJson(time,instance,application,AVG_GC_PAUSE_TIME);
    }
    /**
     * 垃圾回收（GC）- 最大GC暂停时间
     * @return
     */
    public JSON maxGcPauseTime(Date time,String instance,String application){
        return getJson(time,instance,application,MAX_GC_PAUSE_TIME);
    }
    /**
     * 垃圾回收（GC）-内存分配
     * @return
     */
    public JSON gcMemoryAllocated(Date time,String instance,String application){
        return getJson(time,instance,application,GC_MEMORY_ALLOCATED);
    }
    /**
     * 垃圾回收（GC）-内存晋升
     * @return
     */
    public JSON gcMemoryPromoted(Date time,String instance,String application){
        return getJson(time,instance,application,GC_MEMORY_PROMOTED);
    }
    /**
     * 已加载的类的数量
     * @return
     */
    public JSON loadedClassesNum(Date time,String instance,String application){
        return getJson(time,instance,application,LOADED_CLASSES_NUM);
    }
    /**
     * 加载类数量变化
     * @return
     */
    public JSON loadedClassesNumDelta(Date time,String instance,String application){
        return getJson(time,instance,application,LOADED_CLASSES_NUM_DELTA);
    }
    /**
     * 缓冲区-直接缓冲区-已用
     * @return
     */
    public JSON directBuffersUsable(Date time,String instance,String application){
        return getJson(time,instance,application,DIRECT_BUFFERS_USABLE);
    }
    /**
     * 缓冲区-直接缓冲区-总共
     * @return
     */
    public JSON directBuffersMax(Date time,String instance,String application){
        return getJson(time,instance,application,DIRECT_BUFFERS_MAX);
    }
    /**
     * 缓冲区-直接缓冲区-数量
     * @return
     */
    public JSON directBuffersNum(Date time,String instance,String application){
        return getJson(time,instance,application,DIRECT_BUFFERS_NUM);
    }
    /**
     * 缓冲区-映射缓冲区-已用
     * @return
     */
    public JSON mappedBuffersUsable(Date time,String instance,String application){
        return getJson(time,instance,application,MAPPED_BUFFERS_USABLE);
    }
    /**
     * 缓冲区-映射缓冲区-总共
     * @return
     */
    public JSON mappedBuffersMax(Date time,String instance,String application){
        return getJson(time,instance,application,MAPPED_BUFFERS_MAX);
    }
    /**
     * 缓冲区-映射缓冲区-数量
     * @return
     */
    public JSON mappedBuffersNum(Date time,String instance,String application){
        return getJson(time,instance,application,MAPPED_BUFFERS_NUM);
    }

    /**
     * 判断是否替换application和instance
     * @param time 时间
     * @param instance Java程序IP和端口
     * @param application Java程序名
     * @param query 原promQL语句
     * @return
     */
    private static JSON getJson(Date time, String instance, String application, String query) {
        String t = PromQLUtil.parseDateToTime(time);
        promQl = query;
        if (StrUtil.isNotBlank(instance)){
            promQl = promQl.replace(JVM_INSTANCE,instance);
        }
        if (StrUtil.isNotBlank(application)){
            promQl = promQl.replace(JVM_APPLICATION,application);
        }
        String executePromQl = API_PREFIX + INSTANT_QUERY_PREFIX + promQl + "&time="+t;
        return PromQLUtil.executePromQl(executePromQl);
    }

}
